<script setup>
import { ref } from 'vue'

// 配置管理 - 从环境变量或配置文件中获取
const config = {
  // 根据API文档更新为完整的API地址
  API_BASE_URL: 'https://spkqgvqwkeoh.sealoshzh.site/api',
  FILE_MERGE_ENDPOINT: 'merge-files',
  REQUEST_TIMEOUT: 30000, // 30秒
  MAX_RETRIES: 2,
  RETRY_DELAY: 1000 // 1秒
}

// 身份验证相关
const authCode = ref('')
const isAuthenticated = ref(false)

// 文件上传相关
const csvFile = ref(null)
const excelFile = ref(null)
const csvFileName = ref('')
const excelFileName = ref('')
const maxFileSize = 5 * 1024 * 1024 // 5MB

// 整合按钮状态
const canMerge = ref(false)
const isProcessing = ref(false)
const uploadProgress = ref(0)

// 监听身份验证输入
authCode.value = ''
function checkAuth() {
  isAuthenticated.value = authCode.value === '5868'
}

// 处理CSV文件上传
function handleCsvUpload(event) {
  const file = event.target.files[0]
  if (file) {
    if (file.size > maxFileSize) {
      alert('文件大小不能超过5MB')
      event.target.value = ''
      return
    }
    csvFile.value = file
    csvFileName.value = file.name
    checkCanMerge()
  }
}

// 处理Excel文件上传
function handleExcelUpload(event) {
  const file = event.target.files[0]
  if (file) {
    if (file.size > maxFileSize) {
      alert('文件大小不能超过5MB')
      event.target.value = ''
      return
    }
    excelFile.value = file
    excelFileName.value = file.name
    checkCanMerge()
  }
}

// 检查是否可以整合文件
function checkCanMerge() {
  canMerge.value = csvFile.value !== null
}

// 创建带超时的fetch请求
function fetchWithTimeout(url, options, timeout = config.REQUEST_TIMEOUT) {
  return new Promise((resolve, reject) => {
    const controller = new AbortController()
    const timeoutId = setTimeout(() => {
      controller.abort()
      reject(new Error('请求超时，请检查网络连接'))
    }, timeout)

    fetch(url, { ...options, signal: controller.signal })
      .then(response => {
        clearTimeout(timeoutId)
        resolve(response)
      })
      .catch(error => {
        clearTimeout(timeoutId)
        reject(error)
      })
  })
}

// 重试逻辑包装函数
async function fetchWithRetry(url, options, retries = config.MAX_RETRIES) {
  try {
    return await fetchWithTimeout(url, options)
  } catch (error) {
    // 如果不是最后一次重试且错误是可重试的（网络错误、超时等）
    if (retries > 0 && (error.name === 'AbortError' || !error.response)) {
      console.warn(`请求失败，${retries}次重试中...`, error.message)
      // 等待一段时间后重试
      await new Promise(resolve => setTimeout(resolve, config.RETRY_DELAY))
      return fetchWithRetry(url, options, retries - 1)
    }
    throw error
  }
}

// 处理整合文件
async function handleMerge() {
  if (!csvFile.value) return
  
  // 设置处理中状态
  isProcessing.value = true
  uploadProgress.value = 0
  
  try {
    // 创建FormData对象
    const formData = new FormData()
    formData.append('csvFile', csvFile.value)
    
    // 根据是否有Excel文件添加相应参数
    if (excelFile.value) {
      formData.append('excelFile', excelFile.value)
      formData.append('mergeType', 'csv_and_excel')
    } else {
      formData.append('mergeType', 'csv_only')
    }
    
    // 构建完整的API URL
    const apiUrl = `${config.API_BASE_URL}/${config.FILE_MERGE_ENDPOINT}`
    
    // 准备请求选项
    const requestOptions = {
      method: 'POST',
      body: formData,
      // 注意：Content-Type应该由浏览器自动设置为multipart/form-data
      // 不要手动设置Content-Type，因为需要包含boundary信息
      headers: {
        // 这里可以添加身份验证token等
        // 'Authorization': `Bearer ${authToken}`
      }
    }
    
    console.log('发送请求到后端:', apiUrl)
    
    // 发送请求到后端，带重试和超时处理
    const response = await fetchWithRetry(apiUrl, requestOptions)
    
    // 检查响应状态
    if (!response.ok) {
      // 尝试解析错误信息
      let errorMessage = `请求失败: ${response.status} ${response.statusText}`
      try {
        const errorData = await response.json()
        if (errorData.error) {
          errorMessage = errorData.error
        }
      } catch (e) {
        // 如果无法解析JSON错误信息，使用默认错误信息
      }
      throw new Error(errorMessage)
    }
    
    // 检查响应是否为Excel文件
    const contentType = response.headers.get('content-type')
    if (!contentType || !contentType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) {
      throw new Error('服务器返回的不是有效的Excel文件')
    }
    
    // 获取文件名
    let fileName = 'merged_result.xlsx'
    const contentDisposition = response.headers.get('content-disposition')
    if (contentDisposition && contentDisposition.includes('filename=')) {
      const matches = /filename="?([^"]*)"?/.exec(contentDisposition)
      if (matches && matches[1]) {
        fileName = matches[1]
      }
    }
    
    // 获取文件Blob
    const blob = await response.blob()
    
    // 下载文件
    downloadFile(blob, fileName)
    
  } catch (error) {
    console.error('整合文件失败:', error)
    // 根据不同的错误类型提供更具体的错误提示
    let errorMessage = '整合文件失败，请重试'
    if (error.message.includes('超时')) {
      errorMessage = '请求超时，请检查网络连接或稍后再试'
    } else if (error.message.includes('网络')) {
      errorMessage = '网络连接失败，请检查您的网络设置'
    } else if (error.message.includes('Excel文件')) {
      errorMessage = '获取Excel文件失败，请联系管理员'
    } else {
      errorMessage = error.message
    }
    alert(errorMessage)
  } finally {
    // 重置处理状态
    isProcessing.value = false
    uploadProgress.value = 0
  }
}

// 文件下载辅助函数
function downloadFile(blob, fileName) {
  try {
    // 创建下载链接
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = fileName
    
    // 触发下载
    document.body.appendChild(link)
    link.click()
    
    // 清理
    setTimeout(() => {
      document.body.removeChild(link)
      URL.revokeObjectURL(url)
    }, 100)
    
  } catch (error) {
    console.error('下载文件失败:', error)
    alert('文件下载失败，请联系管理员')
  }
}

// 重置文件选择
function resetCsvFile() {
  csvFile.value = null
  csvFileName.value = ''
  document.getElementById('csvFileInput').value = ''
  checkCanMerge()
}

function resetExcelFile() {
  excelFile.value = null
  excelFileName.value = ''
  document.getElementById('excelFileInput').value = ''
  checkCanMerge()
}

// 文件名缩写函数
function truncateFileName(fileName, maxLength = 20) {
  if (fileName.length <= maxLength) {
    return fileName
  }
  
  const extension = fileName.substring(fileName.lastIndexOf('.'))
  const nameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'))
  
  if (extension.length > maxLength - 3) {
    // 如果扩展名太长，直接截断整个文件名
    return fileName.substring(0, maxLength - 3) + '...'
  }
  
  const nameLength = maxLength - extension.length - 3
  return nameWithoutExt.substring(0, nameLength) + '...' + extension
}
</script>

<template>
  <div class="app-container">
    <h1>文件整合工具</h1>
    
    <!-- 身份验证区域 -->
    <div v-if="!isAuthenticated" class="auth-section">
      <label for="authCode">请输入身份验证码：</label>
      <input
        id="authCode"
        v-model="authCode"
        @input="checkAuth"
        type="password"
        placeholder="请输入身份验证码"
        class="auth-input"
      />
      <div v-if="isAuthenticated" class="auth-success">验证通过！</div>
    </div>
    
    <!-- 文件上传区域 -->
    <div class="upload-section">
      <div class="upload-item">
        <input
          id="csvFileInput"
          type="file"
          accept=".csv"
          @change="handleCsvUpload"
          :disabled="!isAuthenticated || isProcessing"
          class="file-input"
        />
        <label for="csvFileInput" class="upload-btn" :disabled="!isAuthenticated || isProcessing">
          <div v-if="!csvFileName" class="btn-content">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" class="icon">
              <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
              <polyline points="14 2 14 8 20 8"/>
              <line x1="16" y1="13" x2="8" y2="13"/>
              <line x1="16" y1="17" x2="8" y2="17"/>
              <polyline points="10 9 9 9 8 9"/>
            </svg>
            上传CSV文件
          </div>
          <div v-else class="file-selected">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" class="icon">
              <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
              <polyline points="14 2 14 8 20 8"/>
              <line x1="16" y1="13" x2="8" y2="13"/>
              <line x1="16" y1="17" x2="8" y2="17"/>
              <polyline points="10 9 9 9 8 9"/>
            </svg>
            <span class="truncated-filename" :title="csvFileName">{{ truncateFileName(csvFileName) }}</span>
            <button @click.stop="resetCsvFile" class="remove-btn">×</button>
          </div>
        </label>
      </div>
      
      <div class="upload-item">
        <input
          id="excelFileInput"
          type="file"
          accept=".xlsx, .xls"
          @change="handleExcelUpload"
          :disabled="!isAuthenticated || isProcessing"
          class="file-input"
        />
        <label for="excelFileInput" class="upload-btn" :disabled="!isAuthenticated || isProcessing">
          <div v-if="!excelFileName" class="btn-content">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" class="icon">
              <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
              <polyline points="14 2 14 8 20 8"/>
              <line x1="16" y1="13" x2="8" y2="13"/>
              <line x1="16" y1="17" x2="8" y2="17"/>
              <polyline points="10 9 9 9 8 9"/>
            </svg>
            上传Excel文件
          </div>
          <div v-else class="file-selected">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" class="icon">
              <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
              <polyline points="14 2 14 8 20 8"/>
              <line x1="16" y1="13" x2="8" y2="13"/>
              <line x1="16" y1="17" x2="8" y2="17"/>
              <polyline points="10 9 9 9 8 9"/>
            </svg>
            <span class="truncated-filename" :title="excelFileName">{{ truncateFileName(excelFileName) }}</span>
            <button @click.stop="resetExcelFile" class="remove-btn">×</button>
          </div>
        </label>
      </div>
    </div>
    
    <!-- 文件大小提示 -->
    <div class="size-tip">
      提示：文件大小限制为5MB以内
    </div>
    
    <!-- 整合按钮 -->
    <div class="merge-section">
      <button
        @click="handleMerge"
        :disabled="!canMerge || isProcessing"
        class="merge-btn"
      >
        整合文件
      </button>
    </div>
    
    <!-- 处理中提示 -->
    <div v-if="isProcessing" class="processing-overlay">
      <div class="processing-content">
        <div class="spinner"></div>
        <p>生成中，请稍等...</p>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* 全局样式 */
:root {
  --primary-color: #42b983;
  --secondary-color: #35495e;
  --light-color: #ffffff;
  --dark-color: #2c3e50;
  --border-color: #e0e0e0;
  --hover-color: #3aa876;
  --disabled-color: #cccccc;
  --error-color: #ff6b6b;
  --background-color: #f8f9fa;
  --card-background: #ffffff;
}

.app-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 2rem;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  background-color: var(--card-background);
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

/* 确保整个页面居中并添加背景色 */
body {
  background-color: var(--background-color);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  min-height: 100vh;
  margin: 0;
  padding: 1rem;
}

h1 {
  text-align: center;
  color: var(--secondary-color);
  margin-bottom: 2rem;
}

/* 身份验证区域 */
.auth-section {
  margin-bottom: 2rem;
  text-align: center;
}

.auth-section label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
  color: var(--secondary-color);
}

.auth-input {
  width: 100%;
  max-width: 300px;
  padding: 0.75rem;
  border: 2px solid var(--border-color);
  border-radius: 4px;
  font-size: 1rem;
  transition: border-color 0.3s ease;
}

.auth-input:focus {
  outline: none;
  border-color: var(--primary-color);
}

.auth-success {
  margin-top: 0.5rem;
  color: var(--primary-color);
  font-weight: 500;
}

/* 文件上传区域 */
.upload-section {
  display: flex;
  gap: 2rem;
  justify-content: center;
  margin-bottom: 1.5rem;
  flex-wrap: nowrap;
}

.upload-item {
  position: relative;
  width: 100%;
  max-width: 300px;
}

/* 文件名缩写样式 */
.truncated-filename {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  text-align: left;
}

/* 调整按钮样式以匹配新的背景色 */
.upload-btn {
  background-color: var(--card-background);
}

.upload-btn:hover:not(:disabled) {
  background-color: rgba(66, 185, 131, 0.05);
}

.file-input {
  display: none;
}

.upload-btn {
  display: block;
  width: 100%;
  padding: 1.5rem;
  border: 2px dashed var(--border-color);
  border-radius: 8px;
  background-color: var(--light-color);
  color: var(--secondary-color);
  text-align: center;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 1rem;
  font-weight: 500;
}

.upload-btn:hover:not(:disabled) {
  border-color: var(--primary-color);
  background-color: #f8fff8;
}

.upload-btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
  background-color: #f5f5f5;
}

.btn-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.file-selected {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.icon {
  width: 48px;
  height: 48px;
  margin-bottom: 0.5rem;
}

.file-selected .icon {
  width: 24px;
  height: 24px;
  margin-bottom: 0;
}

.remove-btn {
  background: var(--error-color);
  color: white;
  border: none;
  border-radius: 50%;
  width: 24px;
  height: 24px;
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.remove-btn:hover {
  background: #ff5252;
}

/* 文件大小提示 */
.size-tip {
  text-align: center;
  color: #666;
  margin-bottom: 2rem;
  font-size: 0.9rem;
}

/* 整合按钮 */
.merge-section {
  text-align: center;
  margin-top: 2rem;
  margin-bottom: 1rem;
  position: relative;
  z-index: 10;
}

.merge-btn {
  padding: 1rem 3rem;
  background-color: var(--primary-color);
  color: var(--dark-color);
  border: none;
  border-radius: 6px;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(66, 185, 131, 0.3);
  min-width: 180px;
}

.merge-btn:hover:not(:disabled) {
  background-color: var(--hover-color);
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(66, 185, 131, 0.4);
}

.merge-btn:disabled {
  background-color: #e0e0e0;
  color: #9e9e9e;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

/* 处理中提示 */
.processing-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.processing-content {
  background-color: white;
  padding: 2rem;
  border-radius: 8px;
  text-align: center;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid var(--primary-color);
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 1rem;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .app-container {
    padding: 1rem;
  }
  
  .upload-section {
    flex-direction: column;
    align-items: center;
  }
  
  .upload-btn {
    padding: 1.25rem;
  }
}
</style>
